/**
 * Created by user on 2018/3/20.
 */
import React, { Component } from 'react'
import { render } from 'react-dom'
import { connect } from 'react-redux'
import GlobalBigImage from './components/GlobalBigImage'
import BeforeScreen from './components/before'
import LiveScreen from './components/live'
import QaScreen from './components/qa'
import EndScreen from './components/end'
import ReplayScreen from './components/replay'
import SilentLoginScreen from './components/login/SilentLogin'
import LoginScreen from './components/login'
import DmComponent from './components/dm'
import ReConnectMask from './components/reConnectMask'
import NotStartMask from './components/notStartMask'
import WaitTeacherMask from './components/waitTeacherMask'
import QuitPcMask from './components/quitPcMask'
import OnlineTeacherComponent from './components/onlineTeacher'
import ReplayOnlineTeacher from './components/onlineTeacher/replayOnlineTeacher'
import { API } from '@utils/config'
import { Request, singleClone, cloneDeep, EventCenter, Data, originData, getStamp, getSeq, MessageCenter, formatSocketMsg, Type, VoicePlayer, VideoPlayer, cloneObj } from './utils/Global'
import { Storage, Keys } from '@utils/LocalStorage'
import SocketManager from './utils/SocketManager'
import ReplaySocket from './utils/ReplaySocket'
import MaterialController from './utils/MaterialController'
import MaterialPlayer from './utils/MaterialPlayer'
import MaterialVideoPlayer from './utils/MaterialVideoPlayer'
import PlayController from '@utils/PlayController'
import ReplayPlayer from '@utils/ReplayPlayer'
import ReplayVideoPlayer from '@utils/ReplayVideoPlayer'
import OutDmSwitch from './components/dm/outDmSwitch'
import QuestionListMask from './components/question/questionListMask'
import {
  DmAction, LiveAction, OnlineTeacherAction,
  MainAction, MaterialAction, ReplayAction,
  QaListAction, QuestionAction, LoginAction
} from './actions'

import './less/app.less'

window.SocketManager = SocketManager
class App extends Component {
  constructor(p) {
    super(p)
    this.teacherLeaveTimer = null
    this.replayBeforeTimer = null
    SocketManager.setListener({
      onNotice: this.onSocketNotice,
      onMessage: this.onSocketMessage
    })
    ReplaySocket.setListener({
      onNotice: this.onReplaySocketNotice
    })
  }
  componentDidMount() {
    EventCenter.addListener('send_msg_to_socket', this.handSendMsgToSocket)
    EventCenter.addListener('do_replay_zan_request', this.doReplayZanRequest)
    EventCenter.addListener('get_replay_data_success', this.initReplayData)
  }
  componentWillUnmount() {
    EventCenter.removeListener('send_msg_to_socket', this.handSendMsgToSocket)
    EventCenter.removeListener('do_replay_zan_request', this.doReplayZanRequest)
    EventCenter.removeListener('get_replay_data_success', this.initReplayData)
  }
  doReplayZanRequest = ({ type, id, from }) => {
    const { dispatch, globalToken } = this.props
    if (from === 'qa') {
      dispatch(QuestionAction.doSelfLikeItem({ msgType: type, id: id }))
    } else if (from === 'list') {
      dispatch(ReplayAction.doSelfLikeItem({ msgType: type, id: id }))
    }
    Request.SendRequest(API.DO_STAR_QUESTION(type, id, globalToken), 'POST', {}, (res) => {
      console.log('succ', res)
    }, () => {
      console.log('err')
    })
  }
  handSendMsgToSocket = (obj) => {
    this.sendMsg(obj.type, obj.data, obj.success, obj.fail)
  }
  sendMsg = (type, data, success, fail) => {
    const { m, a } = Type.SEND_TYPE[type]
    const realMsg = {
      m: m,
      a: a,
      s: {
        seq_time: getSeq(),
        timestamp: getStamp()
      },
      d: data
    }
    SocketManager.send(realMsg, success, fail)
  }
  handleQuestionMsg(msg) {
    if (msg.type === Type.COMMON_TYPE.COMMON_STAR_LIVE) {
      this.handleStarLive(msg)
    }
    if (msg.type === Type.COMMON_TYPE.COMMON_DM_QUESTION) {
      this.handleDmQuestion(msg)
    }
    if (msg.type === Type.COMMON_TYPE.COMMON_DM_ANSWER) {
      this.handleDmAnswer(msg)
    }
    if (msg.type === Type.COMMON_TYPE.COMMON_DM_QUESTION_UP) {
      this.handleDmQuestionUp(msg)
    }
    if (msg.type === Type.COMMON_TYPE.COMMON_QA_ANSWER) {
      this.handleQaAnswer(msg)
    }
    if (msg.type === Type.COMMON_TYPE.COMMON_QA_QUESTION) {
      this.handleQaQuestion(msg)
    }
    if (msg.type === Type.COMMON_TYPE.COMMON_QA_QUESTION_UP) {
      this.handleQaQuestionUp(msg)
    }
    if (msg.type === Type.COMMON_TYPE.COMMON_QA_ANSWER_UP) {
      this.handleQaAnswerUp(msg)
    }
  }
  handleQaAnswerUp(msg) {
    const { dispatch } = this.props
    let isRemoteSelf = msg.sender.id === Data.user.id
    dispatch(QuestionAction.getQuestionOrAnswerMsg({ msg, isRemoteSelf, isSelf: isRemoteSelf, msgType: 'answer_up' }))
    dispatch(QaListAction.getQaQuestionOrAnswerUpMsg({ msg, isRemoteSelf, isSelf: isRemoteSelf, msgType: 'answer_up' }))
  }
  handleQaQuestionUp(msg) {
    const { dispatch } = this.props
    let isRemoteSelf = msg.sender.id === Data.user.id
    dispatch(QuestionAction.getQuestionOrAnswerMsg({ msg, isRemoteSelf, isSelf: isRemoteSelf, msgType: 'question_up' }))
    dispatch(QaListAction.getQaQuestionOrAnswerUpMsg({ msg, isRemoteSelf, isSelf: isRemoteSelf, msgType: 'question_up' }))
  }
  handleQaAnswer(msg) {
    const { dispatch } = this.props
    let isRemoteSelf = msg.sender.id === Data.user.id
    dispatch(QuestionAction.getQuestionOrAnswerMsg({ msg, isRemoteSelf, isSelf: isRemoteSelf, msgType: 'answer' }))
    dispatch(QaListAction.getQaQuestionOrAnswerMsg({ msg, isRemoteSelf, isSelf: isRemoteSelf, msgType: 'answer' }))
  }
  handleQaQuestion(msg) {
    const { dispatch } = this.props
    let isRemoteSelf = msg.sender.id === Data.user.id
    dispatch(QuestionAction.getQuestionOrAnswerMsg({ msg, isRemoteSelf, isSelf: isRemoteSelf, msgType: 'question' }))
    dispatch(QaListAction.getQaQuestionOrAnswerMsg({ msg, isRemoteSelf, isSelf: isRemoteSelf, msgType: 'question' }))
  }
  handleStarLive(msg) {

  }
  handleDmQuestionUp(msg) {
    const { dispatch } = this.props
    let isRemoteSelf = msg.sender.id === Data.user.id
    dispatch(DmAction.getDmQuestionUpMsg({ msg, isRemoteSelf, isSelf: isRemoteSelf }))
    dispatch(QuestionAction.getQuestionOrAnswerMsg({ msg, isRemoteSelf, isSelf: isRemoteSelf, msgType: 'question_up' }))
  }
  handleDmQuestion(msg) {
    const { dispatch } = this.props
    let isRemoteSelf = msg.sender.id === Data.user.id
    dispatch(DmAction.getDmQuestionMsg({ msg, isRemoteSelf, isSelf: isRemoteSelf }))
    dispatch(QuestionAction.getQuestionOrAnswerMsg({ msg, isRemoteSelf, isSelf: isRemoteSelf, msgType: 'question' }))
  }
  handleDmAnswer(msg) {
    const { dispatch } = this.props
    let isRemoteSelf = msg.sender.id === Data.user.id
    dispatch(DmAction.getDmAnswerMsg({ msg, isRemoteSelf, isSelf: isRemoteSelf }))
    dispatch(QuestionAction.getQuestionOrAnswerMsg({ msg, isRemoteSelf, isSelf: isRemoteSelf, msgType: 'answer' }))
  }
  handleRemoteSelfQaTextMsg(msg) {
    const {dispatch} = this.props
    dispatch(QaListAction.getRemoteSelfQaTextMsg({msg}))
  }
  handleTransferQuestionSuccess(msg) {
    const {dispatch} = this.props
    dispatch(QaListAction.getTransferQuestionSuccessMsg({msg}))
    dispatch(QuestionAction.getTransferQuestionSuccessMsg({msg}))
  }
  handleSystemTipMsg(msg) {
    const {screen, dispatch} = this.props
    if ([0, 5].includes(screen)) {
      dispatch(DmAction.getSystemDm(msg))
    }
    if ([10].includes(screen)) {
      dispatch(QaListAction.getSystemQaMsg(msg))
    }
  }
  getUsers(msg) {
    const { getTeachers } = OnlineTeacherAction
    const { dispatch } = this.props
    dispatch(getTeachers(msg.data.teachers))
  }
  handleVideoStart(msg, callback) {
    const { dispatch } = this.props
    const { toggleVideoMask } = LiveAction
    console.log('handleVideoStart', msg)
    dispatch(toggleVideoMask(true))
    const url = msg.data.url
    const time = msg.data.time
    VideoPlayer.play(url, time, () => {

    }, () => {
      callback && callback()
      dispatch(toggleVideoMask(false))
    })
  }
  handleStart(msg) {
    const { dispatch } = this.props
    const { changeScreen } = MainAction
    dispatch(changeScreen(5))
  }
  handleEnd(msg) {
    const { dispatch, info } = this.props
    const { changeScreen } = MainAction
    SocketManager.doClose()
    dispatch(changeScreen(15))
    if (info.type === 2) {
      this.stopMaterial()
    }
  }
  handleStartQa(msg) {
    const { dispatch, info } = this.props
    const { changeScreen } = MainAction
    dispatch(changeScreen(10))
    if (info.type === 2) {
      this.stopMaterial()
    }
  }
  handlePause(msg) {
    const { dispatch } = this.props
    const { toggleLivePause } = LiveAction
    dispatch(toggleLivePause(true))
  }
  handleContinue(msg) {
    const { dispatch } = this.props
    const { toggleLivePause } = LiveAction
    dispatch(toggleLivePause(false))
  }
  handleDm(msg) {
    const { insertDm } = DmAction
    const { dispatch } = this.props
    if (!msg.data.isSecret) {
      dispatch(insertDm(msg))
    }
  }
  handleLiveImage(msg) { }
  handleLiveVoice(msg, callback) {
    const { dispatch } = this.props
    const { changeVoiceStatus } = LiveAction
    const url = msg.data.file
    dispatch(changeVoiceStatus(1))
    VoicePlayer.play(url, () => {
      dispatch(changeVoiceStatus(2))
    }, () => {
      dispatch(changeVoiceStatus(0))
      callback && callback()
    }, () => {
      console.log('error')
      dispatch(changeVoiceStatus(0))
      callback && callback()
    })
  }
  handleLiveSlide(msg) {
    const { dispatch } = this.props
    const { changeIndex } = LiveAction
    const index = msg.data.index
    dispatch(changeIndex(index))
  }
  handleLiveMaterial(msg, callback) {
    const index = msg.data.index
    const time = msg.data.time || 0
    this.startMaterial(index, callback, time)
  }
  handleStartRecord(msg) {
    console.log('handleStartRecord', msg)
    const { setRecordingStatus } = OnlineTeacherAction
    const { dispatch } = this.props
    dispatch(setRecordingStatus(msg.sender.id, true))
  }
  handleStopRecord(msg) {
    const { setRecordingStatus } = OnlineTeacherAction
    const { dispatch } = this.props
    dispatch(setRecordingStatus(msg.sender.id, false))
  }
  handleQaMsg(msg) {
    const { insertQa } = QaListAction
    const { dispatch } = this.props
    dispatch(insertQa(msg))
  }
  handleQaStartRecord(msg) {
    const { setRecordingStatus } = OnlineTeacherAction
    const { dispatch } = this.props
    dispatch(setRecordingStatus(msg.sender.id, true))
  }
  handleQaStopRecord(msg) {
    const { setRecordingStatus } = OnlineTeacherAction
    const { dispatch } = this.props
    dispatch(setRecordingStatus(msg.sender.id, false))
  }
  handleNewMessage = (type, task, callback) => {
    switch (type) {
      case Type.COMMON_TYPE.COMMON_START_VIDEO: {
        this.handleVideoStart(task, callback)
        break
      }
      case Type.COMMON_TYPE.COMMON_START: {
        this.handleStart(task)
        break
      }
      case Type.COMMON_TYPE.COMMON_END: {
        this.handleEnd()
        break
      }
      case Type.COMMON_TYPE.COMMON_START_QA: {
        this.handleStartQa()
        break
      }
      case Type.COMMON_TYPE.COMMON_PAUSE: {
        this.handlePause()
        break
      }
      case Type.COMMON_TYPE.COMMON_CONTINUE: {
        this.handleContinue()
        break
      }
      case Type.COMMON_TYPE.COMMON_DM_TEXT: {
        this.handleDm(task)
        break
      }
      case Type.COMMON_TYPE.COMMON_LIVE_IMAGE: {
        this.handleLiveImage(task)
        break
      }
      case Type.COMMON_TYPE.COMMON_LIVE_VOICE: {
        this.handleLiveVoice(task, callback)
        break
      }
      case Type.COMMON_TYPE.COMMON_LIVE_SLIDE: {
        this.handleLiveSlide(task)
        break
      }
      case Type.COMMON_TYPE.COMMON_LIVE_MATERIAL: {
        this.handleLiveMaterial(task, callback)
        break
      }
      case Type.COMMON_TYPE.COMMON_START_RECORD: {
        this.handleStartRecord(task)
        break
      }
      case Type.COMMON_TYPE.COMMON_STOP_RECORD: {
        this.handleStopRecord(task)
        break
      }
      case Type.COMMON_TYPE.COMMON_QA_START_GIFT:
      case Type.COMMON_TYPE.COMMON_QA_IMAGE:
      case Type.COMMON_TYPE.COMMON_QA_VOICE:
      case Type.COMMON_TYPE.COMMON_QA_TEXT: {
        this.handleQaMsg(task)
        break
      }
      case Type.COMMON_TYPE.COMMON_QA_START_RECORD: {
        this.handleQaStartRecord(task)
        break
      }
      case Type.COMMON_TYPE.COMMON_QA_STOP_RECORD: {
        this.handleQaStopRecord(task)
        break
      }
    }
  }
  onSocketMessage = (msg) => {
    const { info } = this.props
    var m = formatSocketMsg(msg)
    let questionMsgTypeList = [
      Type.COMMON_TYPE.COMMON_DM_QUESTION,
      Type.COMMON_TYPE.COMMON_DM_ANSWER,
      Type.COMMON_TYPE.COMMON_DM_QUESTION_UP,
      Type.COMMON_TYPE.COMMON_DM_ANSWER_UP,
      Type.COMMON_TYPE.COMMON_QA_QUESTION,
      Type.COMMON_TYPE.COMMON_QA_ANSWER,
      Type.COMMON_TYPE.COMMON_QA_QUESTION_UP,
      Type.COMMON_TYPE.COMMON_QA_ANSWER_UP,
      Type.COMMON_TYPE.COMMON_STAR_LIVE
    ]
    if (m && m.type === Type.COMMON_TYPE.COMMON_QA_TEXT && m.sender && m.sender.id === parseInt(Data.user.id, 10)) {
      this.handleRemoteSelfQaTextMsg(m)
    }
    if (m && m.type === Type.COMMON_TYPE.COMMON_QA_TEXT_TRANSFER_QUESTION_SUCCESS) {
      this.handleTransferQuestionSuccess(m)
      return
    }
    if (m && m.type === Type.COMMON_TYPE.COMMON_SYSTEM_TIP) {
      this.handleSystemTipMsg(Object.assign({}, m, {sender: {}}))
      return
    }
    if (m && questionMsgTypeList.includes(m.type)) {
      this.handleQuestionMsg(m)
      return
    }
    if (m && m.type === Type.COMMON_TYPE.COMMON_GET_USERS) {
      this.getUsers(m)
      return
    }
    if (m && m.type === Type.COMMON_TYPE.COMMON_END && info.type === 2) {
      this.handleEnd(m)
      return
    }
    if (m && m.type === Type.COMMON_TYPE.COMMON_START_QA && info.type === 2) {
      this.handleStartQa(m)
      return
    }
    if (m && ((m.sender && m.sender.id !== parseInt(Data.user.id)) || (Type.NEED_HANDLE_SELF_MSG_TYPE.indexOf(m.type) >= 0))) {
      MessageCenter.addMessage(m)
    }
  }
  onSocketNotice = (notice) => {
    const { dispatch } = this.props
    const { toggleQuitPc } = MainAction
    if (notice.code === Type.SOCKET_ERROR_CODE.SYS_ERROR.code && notice.info.msg_code === 7) {
      SocketManager.doClose()
      dispatch(toggleQuitPc(true))
      try {
        console.log('try')
        VoicePlayer.stop()
        VideoPlayer.stop()
        MessageCenter.stop()
        MessageCenter.reset()
        this.stopMaterial()
      } catch (e) {}
      return
    }
    if (notice.code === Type.SOCKET_ERROR_CODE.CON_LOSE.code) {
      const { dispatch } = this.props
      const { toggleReconnect } = MainAction
      dispatch(toggleReconnect(true))
      this.reConnectSocket()
    }
  }
  onReplaySocketNotice = (notice) => {
    const { dispatch } = this.props
    const { toggleQuitPc } = MainAction
    if (notice.code === Type.SOCKET_ERROR_CODE.SYS_ERROR.code && notice.info.msg_code === 7) {
      dispatch(toggleQuitPc(true))
      try {
        console.log('try')
        ReplaySocket.toggleForce(true)
        ReplayPlayer.pause()
        PlayController.stop()
        ReplayVideoPlayer.stop()
        dispatch(ReplayAction.resetAllState())
        dispatch(ReplayAction.updateNoAudio('show', false))
      } catch (e) {}
      return
    }
    if (notice.code === Type.SOCKET_ERROR_CODE.SYS_ERROR.code && notice.info.msg_code === 8) {
      // console.log('onReplaySocketNotice', notice)
      ReplaySocket.toggleForce(true)
      dispatch({type: 'RESET_GLOBAL_STATE'})
      dispatch(LoginAction.changeErrorText('验证码已过期'))
    }
  }
  reConnectSocket = () => {
    const { dispatch } = this.props
    const { toggleReconnect } = MainAction
    SocketManager.connect((bool) => {
      if (bool) {
        dispatch(toggleReconnect(false))
      } else {
        setTimeout(() => {
          this.reConnectSocket()
        }, 1 * 1000)
      }
    })
  }
  loginCallback = (replayObj) => {
    const { info } = this.props
    const data = originData['live']
    MessageCenter.stop()
    MessageCenter.reset()
    MessageCenter.setStartTime(data.info.create_time)
    MessageCenter.setCallback(this.handleNewMessage)
    MessageCenter.start()
    if (info.type !== 2) {
      this.checkNeedPlayVideo()
      this.checkNeedPlayMaterial()
    }
    if (info.type === 2 && replayObj) {
      if (replayObj.type === 'before') {
        this.startReplayBeforeTimer(replayObj.data)
      } else if (replayObj.type === 'live') {
        this.addMaterialToCenter(replayObj.data)
      }
    }
  }
  removeSecretDm() {
    const data = originData['replay'].live
    var filterMsg = data.filter(function(_) {
      var c = formatSocketMsg(_)
      return !(c.type === Type.COMMON_TYPE.COMMON_DM_TEXT && c.data.isSecret)
    })
    originData['replay'].live = filterMsg
  }
  connectReplaySocket(roomId, code, test) {
    ReplaySocket.login({
      code: code,
      roomId: roomId,
      test: test
    })
  }
  initReplayData = () => {
    this.removeSecretDm()
    const data = originData['replay']
    this.connectReplaySocket(data.info.id, Data.code, Data.test)
    const { dispatch } = this.props
    dispatch(QuestionAction.toggleShow(false))
    dispatch(MainAction.changeScreen(20))
    const { info, images, live, faq, audio, questions, answers, plots } = data
    if (!audio) {
      dispatch(ReplayAction.updateNoAudio('show', true))
      return
    }
    dispatch(QuestionAction.initQuestionList({questions: data.questions, answers: data.answers}))
    dispatch(ReplayAction.updateNoAudio('show', false))
    this.initReplayDm(live, questions)
    this.initReplayQa(faq, questions, answers)
    dispatch(MainAction.setInfoData(info))
    dispatch(ReplayAction.initSwiper(images))
    dispatch(ReplayAction.updateFooter('fullTime', this.getFullReplayTime()))
    dispatch(ReplayAction.setReplayMarks(plots))
  }
  getFullReplayTime() {
    const { audio, images, live } = originData['replay']
    var duration = audio && audio.duration || 0
    var audio_time = duration * 1000
    live.map((_) => {
      var s = cloneDeep(formatSocketMsg(_))
      if (s && s.type === Type.COMMON_TYPE.COMMON_START_VIDEO) {
        audio_time += s.data.video_time * 1000
      }
    })
    return audio_time
  }
  initReplayQa(_msgs, _questions, _answers) {
    const { dispatch } = this.props
    const hasPlayedVoiceList = Storage.read(Keys.REPLAY_QA_VOICE_KEY) || []
    const msgs = _msgs.map((_) => {
      var m = formatSocketMsg(_)
      m = cloneDeep(m)
      if (m.type === Type.COMMON_TYPE.COMMON_QA_VOICE) {
        const url = m.data.file
        const status = {
          loading: false,
          playing: false,
          error: false,
          hasPlayed: hasPlayedVoiceList.indexOf(url) >= 0
        }
        m.voiceStatus = status
      }
      if (m.type === Type.COMMON_TYPE.COMMON_QA_QUESTION) {
        m.data.question = singleClone(_questions.find(r => r.id === m.data.question_id))
      }
      if (m.type === Type.COMMON_TYPE.COMMON_QA_ANSWER) {
        m.data.answer = singleClone(_answers.find(r => r.id === m.data.answer_id))
        m.data.question = singleClone(_questions.find(r => r.id === m.data.answer.question_id))
        if (m.data.answer.data.type === 1) {
          m.voiceStatus = {
            loading: false,
            playing: false,
            error: false,
            hasPlayed: hasPlayedVoiceList.indexOf(m.data.answer.data.file) >= 0
          }
        }
      }
      return m
    })
    dispatch(ReplayAction.initQaList(msgs))
  }
  initReplayDm(msgs, questions) {
    const { dispatch } = this.props
    const showInReplayDmType = [ Type.COMMON_TYPE.COMMON_DM_TEXT, Type.COMMON_TYPE.COMMON_DM_QUESTION ]
    var dmMsgs = []
    msgs.map((_) => {
      var current = cloneDeep(formatSocketMsg(_))
      if (current && showInReplayDmType.includes(current.type)) {
        current.show = false
        if (current.type === Type.COMMON_TYPE.COMMON_DM_QUESTION) {
          current.data.question = questions.find(r => r.id === current.data.question_id)
        }
        dmMsgs.push(current)
      }
    })
    dispatch(ReplayAction.setReplayDmList(dmMsgs))
  }
  replayBeforeTimeout() {
    const { materials, dispatch } = this.props
    const { changeScreen } = MainAction
    var needDo = []
    for (var i in materials) {
      var _index = i
      const materialMsg = {
        type: Type.COMMON_TYPE.COMMON_LIVE_MATERIAL,
        data: { index: _index, time: 0 },
        seq_time: getSeq(),
        timestamp: getStamp(),
        isDelay: true,
        sender: {}
      }
      needDo.push(materialMsg)
    }
    dispatch(changeScreen(5))
    this.addMaterialToCenter(needDo)
  }
  startReplayBeforeTimer(data) {
    const { allMaterialTime, exceptTime } = data
    this.replayBeforeTimer && clearInterval(this.replayBeforeTimer)
    this.replayBeforeTimer = setInterval(() => {
      var nowTime = getStamp()
      var diff = exceptTime - nowTime
      if (diff <= 0) {
        clearInterval(this.replayBeforeTimer)
        this.replayBeforeTimeout()
      }
    }, 300)
  }
  addMaterialToCenter(needPlayMaterials) {
    if (needPlayMaterials.length > 0) {
      for (var i in needPlayMaterials) {
        var current = cloneObj(needPlayMaterials[i])
        current.seq_time = getSeq()
        MessageCenter.addMessage(current)
      }
    }
  }
  checkNeedPlayMaterial() {
    const data = originData['live']
    const materials = data.materials
    const lastMaterialMsg = formatSocketMsg(data.last_material)
    const now = getStamp()
    if (!lastMaterialMsg || data.info.status !== 5) {
      return
    }
    const index = lastMaterialMsg.data.index
    const materialTime = this.getMaterialTime(index)
    if ((lastMaterialMsg.timestamp + materialTime) > now) {
      var diff = ((lastMaterialMsg.timestamp + materialTime) - now) / 1000
      if (diff < 3) {
        return
      }

      const materialMsg = {
        type: Type.COMMON_TYPE.COMMON_LIVE_MATERIAL,
        data: {index: index, time: now - lastMaterialMsg.timestamp},
        seq_time: getSeq(),
        timestamp: getStamp(),
        isDelay: true,
        sender: {}
      }
      MessageCenter.addMessage(materialMsg)
    }
  }
  checkNeedPlayVideo() {
    const data = originData['live']
    const lastImage = formatSocketMsg(data.last_image)
    const lastVideo = formatSocketMsg(data.videos[data.videos.length - 1])
    if (data.info.status !== 5) {
      return
    }
    if (!lastImage || !lastVideo || !data.images || (data.images.length === 0)) {
      return
    }
    const currentImage = data.images[lastImage.data.index]
    if (currentImage && currentImage.video_url === lastVideo.data.url) {
      const playedTime = (getStamp() - lastVideo.timestamp) / 1000
      const diff = currentImage.video_time - playedTime
      if (diff > 0) {
        const msg = {
          type: Type.COMMON_TYPE.COMMON_START_VIDEO,
          data: {
            time: playedTime,
            url: currentImage.video_url
          },
          timestamp: getStamp(),
          seq_time: getSeq()
        }
        MessageCenter.addMessage(msg)
      }
    }
  }
  getMaterialTime(index) {
    const { materials } = this.props
    var current = materials[index]
    if (!current) {
      return 0
    }
    const { info, messages, images } = current
    var time = info.audio_length
    for (var i in messages) {
      var c = formatSocketMsg(messages[i])
      if (c.type === Type.COMMON_TYPE.MATERIAL_START_VIDEO) {
        time += (c.data.video_time * 1000)
      }
    }
    return time
  }
  startMaterial(_index, callback, time) {
    var index = parseInt(_index)
    const { toggleShowWait } = MainAction
    const { changeIndex, toggleMaterialShow, toggleLoading, toggleVideoMask } = MaterialAction
    const { dispatch, materials, info } = this.props
    const current = materials[index]
    this.initMaterialController(index)
    const allTime = this.getMaterialTime(index)
    const precent = time / allTime
    const initData = MaterialController.initProgress(precent)
    const { lastTask } = initData
    var currentIndex = 0
    if (lastTask) {
      currentIndex = lastTask.data.index
    }
    dispatch(changeIndex(currentIndex))
    dispatch(toggleMaterialShow(true))
    const url = current.info.audio
    dispatch(toggleLoading(true))
    MaterialPlayer.load(url, initData.realAudioTime / 1000, () => {
      dispatch(toggleLoading(false))
      if (initData.playVideo) {
        dispatch(toggleVideoMask(true))
        MaterialVideoPlayer.play(initData.lastTask.data.url, initData.realVideoTime / 1000, () => {}, () => {
          dispatch(toggleVideoMask(false))
          initData.lastTask.done = true
          MaterialPlayer.start()
          MaterialController.start()
        })
      } else {
        MaterialPlayer.start()
        MaterialController.start()
      }
    }, () => {
      MaterialPlayer.stop()
      MaterialController.stop()
      dispatch(toggleMaterialShow(false))
      callback && callback()
      if (info.type !== 2) {
        return
      }
      const len = materials.length
      if (len <= 0 ) {
        return
      }
      if ((len - 1) === index) {
        dispatch(toggleShowWait(true))
      }
    })
  }
  stopMaterial() {
    const { toggleMaterialShow, toggleVideoMask } = MaterialAction
    const { dispatch } = this.props
    dispatch(toggleMaterialShow(false))
    dispatch(toggleVideoMask(false))
    try{
      MaterialController.stop()
      MaterialController.clear()
      MaterialPlayer.stop()
      MaterialVideoPlayer.stop()
      MessageCenter.deleteAllMaterials()
    } catch (e) {}
  }
  initMaterialController(index, time) {
    const { initSwiper } = MaterialAction
    const { materials, dispatch } = this.props
    var current = materials[index]
    const { info, messages, images } = current
    MaterialController.clear()
    MaterialController.init(info.startTime, messages, images, info.audio_length)
    dispatch(initSwiper(images, 0))
  }
  renderScreen() {
    const silentCode = document.getElementById('htmlCode') && document.getElementById('htmlCode').innerHTML
    const { screen } = this.props
    switch (screen) {
      case -1:
        return silentCode ? (
          <SilentLoginScreen loginCallback={this.loginCallback} />
        ) : <LoginScreen loginCallback={this.loginCallback} />
      case -2:
        return <NotStartMask/>
      case 0:
        return <BeforeScreen />
      case 5:
        return <LiveScreen />
      case 10:
        return <QaScreen />
      case 15:
        return <EndScreen />
      case 20:
        return <ReplayScreen />
    }
  }
  renderDm() {
    const { screen } = this.props
    return (screen === 0 || screen === 5) ? <DmComponent /> : null
  }
  renderOnlineTeacher() {
    const { screen, info } = this.props
    if (info && info.type === 2) {
      return screen === 10 ? <OnlineTeacherComponent /> : null
    }
    return (screen === 5 || screen === 10) ? <OnlineTeacherComponent /> : null
  }
  renderReplayOnlineTeacher() {
    const { screen, info } = this.props
    if (info && info.type === 2 && screen === 5) {
      return <ReplayOnlineTeacher/>
    }
  }
  renderWait() {
    const { showWait, screen, info } = this.props
    return (showWait && screen === 5 && info.type === 2) ? <WaitTeacherMask/> : null
  }
  renderDmSwitch() {
    const { showDm, screen } = this.props
    console.log('1', showDm, screen)
    return (!showDm && (screen === 0 || screen === 5)) ? <OutDmSwitch/> : null
  }
  renderQuestionListMask() {
    const { screen } = this.props
    if ([0, 5, 10, 20].includes(screen)) {
      return <QuestionListMask/>
    }
    return null
  }
  renderGlobalBigImage() {
    return <GlobalBigImage/>
  }
  render() {
    return (
      <div className="root_container">
        <QuitPcMask/>
        <ReConnectMask/>
        { this.renderGlobalBigImage() }
        {this.renderQuestionListMask()}
        {this.renderWait()}
        {this.renderOnlineTeacher()}
        {this.renderReplayOnlineTeacher()}
        {this.renderDm()}
        {this.renderScreen()}
        {this.renderDmSwitch()}
      </div>
    )
  }
}

const mapStateToProps = (state) => {
  return {
    screen: state.MainScreenState.screen,
    materials: state.MainScreenState.materials,
    info: state.MainScreenState.info,
    showWait: state.MainScreenState.showWait,
    showDm: state.DmState.show,
    globalToken: state.MainScreenState.globalToken
  }
}

export default connect(mapStateToProps)(App)
